#!/usr/bin/env python

import bencode
try:
	from collections import OrderedDict
except ImportError:
	from ordereddict import OrderedDict
import hashlib

class TorrentFile(object):
	def __init__(self, inf=None):
		self.info = None
		self.announce = None
		self.announceList = None
		self.creationDate = None
		self.comment = None
		self.createdBy = None
		self.encoding = None
		if inf:
			self.fromFile(inf)

	def fromFile(self, inf):
		return self.fromString(inf.read())

	def fromString(self, ins):
		dat = bencode.bdecode(ins)
		if not len(dat):
			return False
		dat = dat[0]
		for k in ("creation date", "comment", "created by", "encoding", "announce", "announce-list", "info"):
			if k in dat:
				l = k.replace("-", " ").split(" ")
				attr = l[0] + "".join( ( x[0].upper() + x[1:] for x in l[1:] ) )
				setattr(self, attr, dat[k])
		if self.info:
			self.rawinfo = bencode.bencode(self.info)
			ihash = hashlib.sha1()
			ihash.update(self.rawinfo)
			self.infohash = ihash.hexdigest().upper()
			self.size = 0
			if "length" in self.info:
				self.size = self.info["length"]
			elif "files" in self.info:
				for f in self.info["files"]:
					self.size += f["length"]
			if not self.size:
				self.size = None
		
		return True
	
	def toString(self):
		data = OrderedDict([
			("announce", self.announce),
			("announce-list", self.announceList),
			("creation date", self.creationDate),
			("created by", self.createdBy),
			("comment", self.comment),
			("encoding", self.encoding)
			#("info" , self.info)
		])
		data = dict(filter(lambda x: data[x[0]] is not None, data.items()))
		return bencode.bencode(data) + self.rawinfo
	
	def describe(self):
		if "name" in self.info:
			desc = [ "Name : %s" % self.info["name"] ]
		desc += [
			"Size (bytes) : %d" % self.size,
			"Hash : %s" % self.infohash,
			"Announce : %s" % self.announce,
			"Announce list : %s" % self.announceList,
			"Comment : %s" % self.comment,
			"Created by : %s" % self.createdBy,
			"Creation date (seconds since epoch) : %s" % self.creationDate,
			"Encoding : %s" % self.encoding,
		]
		if "piece length" in self.info:
			desc.append("Piece length : %d" % self.info["piece length"])
		if "private" in self.info:
			desc.append("Private : %s" % bool(self.info["private"]))
		return desc
